home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- #include "WINGsP.h"
-
- typedef struct W_Button {
- W_Class widgetClass;
- WMView *view;
-
- char *caption;
-
- char *altCaption;
-
- WMFont *font;
-
- WMColor *textColor;
- WMColor *altTextColor;
- WMColor *disTextColor;
-
- W_Pixmap *image;
- W_Pixmap *altImage;
-
- W_Pixmap *dimage;
-
- void *clientData;
- WMAction *action;
-
- int tag;
-
- int groupIndex;
-
- float periodicDelay;
- float periodicInterval;
-
- WMHandlerID *timer; /* for continuous mode */
-
- struct {
- WMButtonType type:4;
- WMImagePosition imagePosition:4;
- WMAlignment alignment:2;
-
- unsigned int selected:1;
-
- unsigned int enabled:1;
-
- unsigned int bordered:1;
-
- unsigned int springLoaded:1;
-
- unsigned int pushIn:1; /* change relief while pushed */
-
- unsigned int pushLight:1; /* highlight while pushed */
-
- unsigned int pushChange:1; /* change caption while pushed */
-
- unsigned int stateLight:1; /* state indicated by highlight */
-
- unsigned int stateChange:1; /* state indicated by caption change */
-
- unsigned int statePush:1; /* state indicated by relief */
-
- unsigned int continuous:1; /* continually perform action */
- /* */
- unsigned int prevSelected:1;
-
- unsigned int pushed:1;
-
- unsigned int wasPushed:1;
-
- unsigned int redrawPending:1;
-
- unsigned int addedObserver:1;
- } flags;
- } Button;
-
-
-
- #define DEFAULT_BUTTON_WIDTH 60
- #define DEFAULT_BUTTON_HEIGHT 24
- #define DEFAULT_BUTTON_ALIGNMENT WACenter
- #define DEFAULT_BUTTON_IS_BORDERED True
-
-
- #define DEFAULT_RADIO_WIDTH 100
- #define DEFAULT_RADIO_HEIGHT 20
- #define DEFAULT_RADIO_ALIGNMENT WALeft
- #define DEFAULT_RADIO_IMAGE_POSITION WIPLeft
- #define DEFAULT_RADIO_TEXT "Radio"
-
-
- #define DEFAULT_SWITCH_WIDTH 100
- #define DEFAULT_SWITCH_HEIGHT 20
- #define DEFAULT_SWITCH_ALIGNMENT WALeft
- #define DEFAULT_SWITCH_IMAGE_POSITION WIPLeft
- #define DEFAULT_SWITCH_TEXT "Switch"
-
-
- static void destroyButton(Button *bPtr);
- static void paintButton(Button *bPtr);
-
- static void handleEvents(XEvent *event, void *data);
- static void handleActionEvents(XEvent *event, void *data);
-
-
- static char *WMPushedRadioNotification="WMPushedRadioNotification";
-
-
- #define NFONT(b) (b)->view->screen->normalFont
-
-
- WMButton*
- WMCreateCustomButton(WMWidget *parent, int behaviourMask)
- {
- Button *bPtr;
-
- bPtr = wmalloc(sizeof(Button));
- memset(bPtr, 0, sizeof(Button));
-
- bPtr->widgetClass = WC_Button;
-
- bPtr->view = W_CreateView(W_VIEW(parent));
- if (!bPtr->view) {
- wfree(bPtr);
- return NULL;
- }
- bPtr->view->self = bPtr;
-
- bPtr->flags.type = 0;
-
- bPtr->flags.springLoaded = (behaviourMask & WBBSpringLoadedMask)!=0;
- bPtr->flags.pushIn = (behaviourMask & WBBPushInMask)!=0;
- bPtr->flags.pushChange = (behaviourMask & WBBPushChangeMask)!=0;
- bPtr->flags.pushLight = (behaviourMask & WBBPushLightMask)!=0;
- bPtr->flags.stateLight = (behaviourMask & WBBStateLightMask)!=0;
- bPtr->flags.stateChange = (behaviourMask & WBBStateChangeMask)!=0;
- bPtr->flags.statePush = (behaviourMask & WBBStatePushMask)!=0;
-
- W_ResizeView(bPtr->view, DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
- bPtr->flags.alignment = DEFAULT_BUTTON_ALIGNMENT;
- bPtr->flags.bordered = DEFAULT_BUTTON_IS_BORDERED;
-
- bPtr->flags.enabled = 1;
-
-
- WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask,
- handleEvents, bPtr);
-
- WMCreateEventHandler(bPtr->view, ButtonPressMask|ButtonReleaseMask
- |EnterWindowMask|LeaveWindowMask,
- handleActionEvents, bPtr);
-
- W_ResizeView(bPtr->view, DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
- bPtr->flags.alignment = DEFAULT_BUTTON_ALIGNMENT;
- bPtr->flags.bordered = DEFAULT_BUTTON_IS_BORDERED;
-
- return bPtr;
- }
-
-
-
- WMButton*
- WMCreateButton(WMWidget *parent, WMButtonType type)
- {
- W_Screen *scrPtr = W_VIEW(parent)->screen;
- Button *bPtr;
-
- switch (type) {
- case WBTMomentaryPush:
- bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask
- |WBBPushInMask|WBBPushLightMask);
- break;
-
- case WBTMomentaryChange:
- bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask
- |WBBPushChangeMask);
- break;
-
- case WBTPushOnPushOff:
- bPtr = WMCreateCustomButton(parent, WBBPushInMask|WBBStatePushMask
- |WBBStateLightMask);
- break;
-
- case WBTToggle:
- bPtr = WMCreateCustomButton(parent, WBBPushInMask|WBBStateChangeMask
- |WBBStatePushMask);
- break;
-
- case WBTOnOff:
- bPtr = WMCreateCustomButton(parent, WBBStateLightMask);
- break;
-
- case WBTSwitch:
- bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
- bPtr->flags.bordered = 0;
- bPtr->image = WMRetainPixmap(scrPtr->checkButtonImageOff);
- bPtr->altImage = WMRetainPixmap(scrPtr->checkButtonImageOn);
- break;
-
- case WBTRadio:
- bPtr = WMCreateCustomButton(parent, WBBStateChangeMask);
- bPtr->flags.bordered = 0;
- bPtr->image = WMRetainPixmap(scrPtr->radioButtonImageOff);
- bPtr->altImage = WMRetainPixmap(scrPtr->radioButtonImageOn);
- break;
-
- default:
- case WBTMomentaryLight:
- bPtr = WMCreateCustomButton(parent, WBBSpringLoadedMask
- |WBBPushLightMask);
- bPtr->flags.bordered = 1;
- break;
- }
-
- bPtr->flags.type = type;
-
- if (type==WBTRadio) {
- W_ResizeView(bPtr->view, DEFAULT_RADIO_WIDTH, DEFAULT_RADIO_HEIGHT);
- WMSetButtonText(bPtr, DEFAULT_RADIO_TEXT);
- bPtr->flags.alignment = DEFAULT_RADIO_ALIGNMENT;
- bPtr->flags.imagePosition = DEFAULT_RADIO_IMAGE_POSITION;
- } else if (type==WBTSwitch) {
- W_ResizeView(bPtr->view, DEFAULT_SWITCH_WIDTH, DEFAULT_SWITCH_HEIGHT);
- WMSetButtonText(bPtr, DEFAULT_SWITCH_TEXT);
- bPtr->flags.alignment = DEFAULT_SWITCH_ALIGNMENT;
- bPtr->flags.imagePosition = DEFAULT_SWITCH_IMAGE_POSITION;
- }
-
- return bPtr;
- }
-
-
- static void
- updateDisabledMask(WMButton *bPtr)
- {
- WMScreen *scr = WMWidgetScreen(bPtr);
- Display *dpy = scr->display;
-
- if (bPtr->image) {
- XGCValues gcv;
-
- bPtr->dimage->mask = XCreatePixmap(dpy, scr->stipple,
- bPtr->dimage->width,
- bPtr->dimage->height, 1);
-
- XSetForeground(dpy, scr->monoGC, 0);
- XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0,
- bPtr->dimage->width, bPtr->dimage->height);
-
- gcv.foreground = 1;
- gcv.background = 0;
- gcv.stipple = scr->stipple;
- gcv.fill_style = FillStippled;
- gcv.clip_mask = bPtr->image->mask;
- gcv.clip_x_origin = 0;
- gcv.clip_y_origin = 0;
-
- XChangeGC(dpy, scr->monoGC, GCForeground|GCBackground|GCStipple
- |GCFillStyle|GCClipMask|GCClipXOrigin|GCClipYOrigin, &gcv);
-
- XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0,
- bPtr->dimage->width, bPtr->dimage->height);
-
- gcv.fill_style = FillSolid;
- gcv.clip_mask = None;
- XChangeGC(dpy, scr->monoGC, GCFillStyle|GCClipMask, &gcv);
- }
- }
-
- void
- WMSetButtonImageDefault(WMButton *bPtr)
- {
- WMSetButtonImage (bPtr, WMWidgetScreen(bPtr)->buttonArrow);
- WMSetButtonAltImage (bPtr, WMWidgetScreen(bPtr)->pushedButtonArrow);
- }
-
- void
- WMSetButtonImage(WMButton *bPtr, WMPixmap *image)
- {
- if (bPtr->image!=NULL)
- WMReleasePixmap(bPtr->image);
- bPtr->image = WMRetainPixmap(image);
-
- if (bPtr->dimage) {
- bPtr->dimage->pixmap = None;
- WMReleasePixmap(bPtr->dimage);
- bPtr->dimage = NULL;
- }
-
- if (image) {
- bPtr->dimage = WMCreatePixmapFromXPixmaps(WMWidgetScreen(bPtr),
- image->pixmap, None,
- image->width, image->height,
- image->depth);
- updateDisabledMask(bPtr);
- }
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
- void
- WMSetButtonAltImage(WMButton *bPtr, WMPixmap *image)
- {
- if (bPtr->altImage!=NULL)
- WMReleasePixmap(bPtr->altImage);
- bPtr->altImage = WMRetainPixmap(image);
-
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
- void
- WMSetButtonImagePosition(WMButton *bPtr, WMImagePosition position)
- {
- bPtr->flags.imagePosition = position;
-
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
-
-
- void
- WMSetButtonTextAlignment(WMButton *bPtr, WMAlignment alignment)
- {
- bPtr->flags.alignment = alignment;
-
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
- void
- WMSetButtonText(WMButton *bPtr, char *text)
- {
- if (bPtr->caption)
- wfree(bPtr->caption);
-
- if (text!=NULL) {
- bPtr->caption = wstrdup(text);
- } else {
- bPtr->caption = NULL;
- }
-
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
- void
- WMSetButtonAltText(WMButton *bPtr, char *text)
- {
- if (bPtr->altCaption)
- wfree(bPtr->altCaption);
-
- if (text!=NULL) {
- bPtr->altCaption = wstrdup(text);
- } else {
- bPtr->altCaption = NULL;
- }
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
- void
- WMSetButtonTextColor(WMButton *bPtr, WMColor *color)
- {
- if (bPtr->textColor)
- WMReleaseColor(bPtr->textColor);
-
- bPtr->textColor = WMRetainColor(color);
- }
-
-
- void
- WMSetButtonAltTextColor(WMButton *bPtr, WMColor *color)
- {
- if (bPtr->altTextColor)
- WMReleaseColor(bPtr->altTextColor);
-
- bPtr->altTextColor = WMRetainColor(color);
- }
-
-
- void
- WMSetButtonDisabledTextColor(WMButton *bPtr, WMColor *color)
- {
- if (bPtr->disTextColor)
- WMReleaseColor(bPtr->disTextColor);
-
- bPtr->disTextColor = WMRetainColor(color);
- }
-
-
- void
- WMSetButtonSelected(WMButton *bPtr, int isSelected)
- {
- bPtr->flags.selected = isSelected;
-
- WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
- int
- WMGetButtonSelected(WMButton *bPtr)
- {
- CHECK_CLASS(bPtr, WC_Button);
-
- return bPtr->flags.selected;
- }
-
-
- void
- WMSetButtonBordered(WMButton *bPtr, int isBordered)
- {
- bPtr->flags.bordered = isBordered;
-
- if (bPtr->view->flags.realized) {
- paintButton(bPtr);
- }
- }
-
-
- void
- WMSetButtonFont(WMButton *bPtr, WMFont *font)
- {
- if (bPtr->font)
- WMReleaseFont(bPtr->font);
-
- bPtr->font = WMRetainFont(font);
- }
-
-
- void
- WMSetButtonEnabled(WMButton *bPtr, Bool flag)
- {
- bPtr->flags.enabled = flag;
-
- if (bPtr->view->flags.mapped) {
- paintButton(bPtr);
- }
- }
-
-
- void
- WMSetButtonTag(WMButton *bPtr, int tag)
- {
- bPtr->tag = tag;
- }
-
-
-
- void
- WMPerformButtonClick(WMButton *bPtr)
- {
- CHECK_CLASS(bPtr, WC_Button);
-
- if (!bPtr->flags.enabled)
- return;
-
- bPtr->flags.pushed = 1;
- bPtr->flags.selected = 1;
-
- if (bPtr->view->flags.mapped) {
- paintButton(bPtr);
- XFlush(WMScreenDisplay(WMWidgetScreen(bPtr)));
- wusleep(20000);
- }
-
- if (bPtr->groupIndex>0) {
- WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
- }
-
- if (bPtr->action)
- (*bPtr->action)(bPtr, bPtr->clientData);
-
- bPtr->flags.pushed = 0;
-
- if (bPtr->view->flags.mapped)
- paintButton(bPtr);
- }
-
-
-
- void
- WMSetButtonAction(WMButton *bPtr, WMAction *action, void *clientData)
- {
- CHECK_CLASS(bPtr, WC_Button);
-
- bPtr->action = action;
-
- bPtr->clientData = clientData;
- }
-
-
-
-
- static void
- radioPushObserver(void *observerData, WMNotification *notification)
- {
- WMButton *bPtr = (WMButton*)observerData;
- WMButton *pushedButton = (WMButton*)WMGetNotificationObject(notification);
-
- if (bPtr!=pushedButton && pushedButton->groupIndex == bPtr->groupIndex
- && bPtr->groupIndex!=0) {
- if (bPtr->flags.selected) {
- bPtr->flags.selected = 0;
- paintButton(bPtr);
- }
- }
- }
-
-
-
- void
- WMGroupButtons(WMButton *bPtr, WMButton *newMember)
- {
- static int tagIndex = 0;
-
- CHECK_CLASS(bPtr, WC_Button);
- CHECK_CLASS(newMember, WC_Button);
-
- if (!bPtr->flags.addedObserver) {
- WMAddNotificationObserver(radioPushObserver, bPtr,
- WMPushedRadioNotification, NULL);
- bPtr->flags.addedObserver = 1;
- }
- if (!newMember->flags.addedObserver) {
- WMAddNotificationObserver(radioPushObserver, newMember,
- WMPushedRadioNotification, NULL);
- newMember->flags.addedObserver = 1;
- }
-
- if (bPtr->groupIndex==0) {
- bPtr->groupIndex = ++tagIndex;
- }
- newMember->groupIndex = bPtr->groupIndex;
- }
-
-
- void
- WMSetButtonContinuous(WMButton *bPtr, Bool flag)
- {
- bPtr->flags.continuous = flag;
- if (bPtr->timer) {
- WMDeleteTimerHandler(bPtr->timer);
- bPtr->timer = NULL;
- }
- }
-
-
- void
- WMSetButtonPeriodicDelay(WMButton *bPtr, float delay, float interval)
- {
- bPtr->periodicInterval = interval;
- bPtr->periodicDelay = delay;
- }
-
-
-
- static void
- paintButton(Button *bPtr)
- {
- W_Screen *scrPtr = bPtr->view->screen;
- WMReliefType relief;
- int offset;
- char *caption;
- WMPixmap *image;
- WMColor *textColor;
- GC gc;
-
- gc = NULL;
- caption = bPtr->caption;
-
- if (bPtr->flags.enabled) {
- textColor = (bPtr->textColor!=NULL
- ? bPtr->textColor : scrPtr->black);
- } else {
- textColor = (bPtr->disTextColor!=NULL
- ? bPtr->disTextColor : scrPtr->darkGray);
- }
-
- if (bPtr->flags.enabled || !bPtr->dimage)
- image = bPtr->image;
- else
- image = bPtr->dimage;
- offset = 0;
- if (bPtr->flags.bordered)
- relief = WRRaised;
- else
- relief = WRFlat;
-
- if (bPtr->flags.selected) {
- if (bPtr->flags.stateLight) {
- gc = WMColorGC(scrPtr->white);
- textColor = scrPtr->black;
- }
-
- if (bPtr->flags.stateChange) {
- if (bPtr->altCaption)
- caption = bPtr->altCaption;
- if (bPtr->altImage)
- image = bPtr->altImage;
- if (bPtr->altTextColor)
- textColor = bPtr->altTextColor;
- }
-
- if (bPtr->flags.statePush && bPtr->flags.bordered) {
- relief = WRSunken;
- offset = 1;
- }
- }
-
- if (bPtr->flags.pushed) {
- if (bPtr->flags.pushIn) {
- relief = WRPushed;
- offset = 1;
- }
- if (bPtr->flags.pushLight) {
- gc = WMColorGC(scrPtr->white);
- textColor = scrPtr->black;
- }
-
- if (bPtr->flags.pushChange) {
- if (bPtr->altCaption)
- caption = bPtr->altCaption;
- if (bPtr->altImage)
- image = bPtr->altImage;
- if (bPtr->altTextColor)
- textColor = bPtr->altTextColor;
- }
- }
-
- W_PaintTextAndImage(bPtr->view, True, WMColorGC(textColor),
- (bPtr->font!=NULL ? bPtr->font : scrPtr->normalFont),
- relief, caption, bPtr->flags.alignment, image,
- bPtr->flags.imagePosition, gc, offset);
- }
-
-
-
- static void
- handleEvents(XEvent *event, void *data)
- {
- Button *bPtr = (Button*)data;
-
- CHECK_CLASS(data, WC_Button);
-
-
- switch (event->type) {
- case Expose:
- if (event->xexpose.count!=0)
- break;
- paintButton(bPtr);
- break;
-
- case DestroyNotify:
- destroyButton(bPtr);
- break;
- }
- }
-
-
- static void
- autoRepeat(void *data)
- {
- Button *bPtr = (Button*)data;
-
- if (bPtr->action && bPtr->flags.pushed)
- (*bPtr->action)(bPtr, bPtr->clientData);
-
- bPtr->timer = WMAddTimerHandler((int)(bPtr->periodicInterval*1000),
- autoRepeat, bPtr);
- }
-
-
- static void
- handleActionEvents(XEvent *event, void *data)
- {
- Button *bPtr = (Button*)data;
- int doclick = 0, dopaint=0;
-
- CHECK_CLASS(data, WC_Button);
-
- if (!bPtr->flags.enabled)
- return;
-
- switch (event->type) {
- case EnterNotify:
- if (bPtr->groupIndex == 0) {
- bPtr->flags.pushed = bPtr->flags.wasPushed;
- if (bPtr->flags.pushed) {
- bPtr->flags.selected = !bPtr->flags.prevSelected;
- dopaint = 1;
- }
- }
- break;
-
- case LeaveNotify:
- if (bPtr->groupIndex == 0) {
- bPtr->flags.wasPushed = bPtr->flags.pushed;
- if (bPtr->flags.pushed) {
- bPtr->flags.selected = bPtr->flags.prevSelected;
- dopaint = 1;
- }
- bPtr->flags.pushed = 0;
- }
- break;
-
- case ButtonPress:
- if (event->xbutton.button == Button1) {
- if (bPtr->groupIndex>0) {
- if (!bPtr->flags.selected)
- doclick = 1;
- bPtr->flags.pushed = 1;
- bPtr->flags.selected = 1;
- dopaint = 1;
- break;
- }
- bPtr->flags.wasPushed = 0;
- bPtr->flags.pushed = 1;
- bPtr->flags.prevSelected = bPtr->flags.selected;
- bPtr->flags.selected = !bPtr->flags.selected;
- dopaint = 1;
-
- if (bPtr->flags.continuous && !bPtr->timer) {
- bPtr->timer = WMAddTimerHandler((int)(bPtr->periodicDelay*1000),
- autoRepeat, bPtr);
- }
- }
- break;
-
- case ButtonRelease:
- if (event->xbutton.button == Button1) {
- if (bPtr->flags.pushed) {
- if (bPtr->groupIndex==0)
- doclick = 1;
- dopaint = 1;
- if (bPtr->flags.springLoaded) {
- bPtr->flags.selected = bPtr->flags.prevSelected;
- }
- }
- bPtr->flags.pushed = 0;
- }
- if (bPtr->timer) {
- WMDeleteTimerHandler(bPtr->timer);
- bPtr->timer = NULL;
- }
- break;
- }
-
- if (dopaint)
- paintButton(bPtr);
-
- if (doclick) {
- if (bPtr->flags.selected && bPtr->groupIndex>0) {
- WMPostNotificationName(WMPushedRadioNotification, bPtr, NULL);
- }
-
- if (bPtr->action)
- (*bPtr->action)(bPtr, bPtr->clientData);
- }
- }
-
-
-
- static void
- destroyButton(Button *bPtr)
- {
- if (bPtr->flags.addedObserver) {
- WMRemoveNotificationObserver(bPtr);
- }
-
- if (bPtr->timer)
- WMDeleteTimerHandler(bPtr->timer);
-
- if (bPtr->font)
- WMReleaseFont(bPtr->font);
-
- if (bPtr->caption)
- wfree(bPtr->caption);
-
- if (bPtr->altCaption)
- wfree(bPtr->altCaption);
-
- if (bPtr->textColor)
- WMReleaseColor(bPtr->textColor);
-
- if (bPtr->altTextColor)
- WMReleaseColor(bPtr->altTextColor);
-
- if (bPtr->disTextColor)
- WMReleaseColor(bPtr->disTextColor);
-
- if (bPtr->image)
- WMReleasePixmap(bPtr->image);
-
- if (bPtr->dimage) {
- /* yuck.. kluge */
- bPtr->dimage->pixmap = None;
-
- WMReleasePixmap(bPtr->dimage);
- }
- if (bPtr->altImage)
- WMReleasePixmap(bPtr->altImage);
-
- wfree(bPtr);
- }
-
-
-